package gu.sql2java;

import static com.google.common.base.Preconditions.checkNotNull;

import java.lang.reflect.Method;
import java.util.Arrays;

import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;

class NameUtilities {
	/**
	 * 将'_'连接的字母数字混合字符串转换为驼峰命名法规则的字符串，
	 * 如：'hello_world_tom'转换为'helloWorldTom'
	 * @param name
	 * @param firstUpperCase 为true时首字母大写
	 * @return 返回以驼峰命名法转换后的字符串
	 */
	static final String toCamelCase(String name, boolean firstUpperCase) {
		if(name == null){
			return null;
		}
		StringBuffer buffer = new StringBuffer(name.length());
		char[] list = name.toLowerCase().toCharArray();
		for (int i = 0; i < list.length; ++i) {
			if (i == 0 && firstUpperCase) {
				buffer.append(Character.toUpperCase(list[i]));
				continue;
			}
			if (list[i] == '_' && i + 1 < list.length && i != 0) {
				buffer.append(Character.toUpperCase(list[++i]));
				continue;
			}
			buffer.append(list[i]);
		}
		return buffer.toString();
	}
	
	/*
	 * Utility routine to paper over array type names
	 */
	static final String getTypeName(Class<?> type) {
		if(null == type){
			return null;
		}else	if (type.isArray()) {
			return getTypeName(type.getComponentType()).concat("[]");
		} else{
			return type.getName().replaceAll("\\$", "\\.");
		}			
	}
	private static final Function<Class<?>, String> TYPESTR_FUN= new  Function<Class<?>, String>(){
		@Override
		public String apply(Class<?> input) {
			return getTypeName(input);
		}		
	}; 
	static final String signatureOf(Method method){
		checkNotNull(method,"method is null");
		return new StringBuilder()
			.append(method.getName())
			.append('(')
			.append(Joiner.on(',').join(Lists.transform(Arrays.asList(method.getParameterTypes()), TYPESTR_FUN)))
			.append(')').toString();
		
	}
	static final String signatureOf(Method method, boolean withReturnType, boolean withArgName){
		checkNotNull(method,"method is null");
		StringBuilder builder = new StringBuilder();
		if(withReturnType){
			builder.append(getTypeName(method.getReturnType())).append(" ");
		}
		builder.append(method.getName()).append('(');
		if(!withArgName){
			builder.append(Joiner.on(',').join(Lists.transform(Arrays.asList(method.getParameterTypes()), TYPESTR_FUN)));
		}else{
			int i = 0;
			for(Class<?> type : method.getParameterTypes()){
				if(i > 0){
					builder.append(",");
				}
				builder.append(getTypeName(type)).append(" arg").append(i);
				i++;
			}
		}
		builder.append(')').toString();
		return builder.toString();
		
	}
	static final Function<Method, String> METHODSIGN_FUN= new  Function<Method, String>(){
		@Override
		public String apply(Method input) {
			return signatureOf(input);
		}		
	}; 
}
